package org.deltaset.faces;

import java.io.Serializable;

/**
 *
 * @author Dimitar Makariev
 */
public final class PageInfo implements Serializable {

    private static final long serialVersionUID = 5715138212389353221L;
    private final int maxItemsOnPage; //on page -parameter
    private final long itemCount; //parameter
    private final long currentPage; //parameter
    private final long numberOfPages; //this is also last page..
    private final int firstItemIndex;
    private final int lastItemIndex;
    private final boolean next;
    private final boolean previous;
    private final boolean isCounterUsed;

    PageInfo(int maxItemsOnPage, long itemCount, long currentPage, boolean isCounterUsed) {
        /* TODO: better documentation and better design !
         * 
         * when isCounterUsed==false
         *     the itemCount is equal to the (currentPage + 1);
         *     getItemCount getter will return -1
         *     next is true if itemCount > maxItemsOnPage
         * 
         */

        this.maxItemsOnPage = maxItemsOnPage;
        this.itemCount = itemCount;
        this.numberOfPages = (long) Math.ceil((double) itemCount / (double) maxItemsOnPage);
        this.currentPage = (false == isCounterUsed) ? currentPage : Math.min(this.numberOfPages, (currentPage < 1) ? 1 : currentPage);
        this.firstItemIndex = (int) (this.currentPage - 1) * maxItemsOnPage;

        this.next = (false == isCounterUsed) ? (itemCount > maxItemsOnPage) : (this.currentPage < this.numberOfPages);
        this.previous = this.currentPage > 1;

        this.lastItemIndex = (false == isCounterUsed) ? this.firstItemIndex + (int) itemCount - (this.next ? 2 : 1) : Math.min(this.firstItemIndex + maxItemsOnPage, (int) itemCount) - 1;


        this.isCounterUsed = isCounterUsed;
    }

    static int calculateFirstResult(final long currentPage, final int maxItemsOnPage) {
        return (int) (currentPage - 1) * maxItemsOnPage;
    }

    //calculated
    public long getNumberOfPages() {
        return (false == isCounterUsed) ? -1 : numberOfPages;
    }

    public long getItemCount() {
        return (false == isCounterUsed) ? -1 : itemCount;
    }

    public long getCurrentPage() {
        return currentPage;
    }

    public boolean getHasNext() {
        return next;
    }

    public boolean getHasPrevious() {
        return previous;
    }

    public boolean getHasItems() {
        return itemCount > 0;
    }

    public long getNextPage() {
        return this.getHasNext() ? this.getCurrentPage() + 1 : this.getCurrentPage();
    }

    public long getPreviousPage() {
        return this.getHasPrevious() ? this.getCurrentPage() - 1 : this.getCurrentPage();
    }

    public int getMaxItemsOnPage() {
        return maxItemsOnPage;
    }

    public int getFirstItemIndex() {
        return firstItemIndex;
    }

    public int getLastItemIndex() {
        return lastItemIndex;
    }
}
